package com.remote;

import java.io.InputStream;


import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;

public class RemoteOperations {


	private String userName;
	private boolean isPasswordBasedAuthentication;
	private String password;
	private String privateKey;
	private String host;
	private long commandExecutionTimeout = 300000;

	public RemoteOperations(String userName, String passwordOrPrivateKey,
			String host, boolean isPasswordBasedAuthentication) {
		super();
		this.userName = userName;
		if (isPasswordBasedAuthentication)
			this.password = passwordOrPrivateKey;
		else
			this.privateKey = passwordOrPrivateKey;
		this.host = host;
		this.isPasswordBasedAuthentication = isPasswordBasedAuthentication;

	}

	public String remoteExecute(String command) {

		try {
			System.out.println("Connecting to ... Host : " + host + " User : "
					+ userName + " Password / Private Key : " + password
					+ " Authentication Mode (isPasswordBasedAuthentication): "
					+ isPasswordBasedAuthentication);

			if (!this.isPasswordBasedAuthentication)
				command = "sudo " + command;
			System.out.println("Executing Command : " + command);
			StringBuffer stringBuffer = new StringBuffer();

			JSch jsch = new JSch();

			Session session = getRemoteSession(jsch);

			Channel channel = session.openChannel("exec");
			((ChannelExec) channel).setCommand(command);

			channel.setInputStream(null);

			((ChannelExec) channel).setErrStream(System.err);

			InputStream in = channel.getInputStream();

			channel.connect();

			byte[] tmp = new byte[1024];
			long startTime = System.currentTimeMillis();

			while ((System.currentTimeMillis() - startTime) < commandExecutionTimeout) {
				while (in.available() > 0) {
					int i = in.read(tmp, 0, 1024);
					if (i < 0)
						break;
					stringBuffer.append((new String(tmp, 0, i)));
				}
				if (channel.isClosed()) {
					System.out.println("Exiting Command : Exit Status : "
							+ channel.getExitStatus()
							+ " With Command Output : "
							+ stringBuffer.toString());
					stringBuffer.append("Exit Status:"
							+ channel.getExitStatus());
					break;
				}
				try {
					Thread.sleep(1000);
				} catch (Exception ee) {
				}
			}
			channel.disconnect();
			session.disconnect();
			return stringBuffer.toString();
		} catch (Exception e) {
			return e.toString();
		}

	}

	private Session getRemoteSession(JSch jsch) throws JSchException {
		UserInfo ui = null;
	
			jsch.addIdentity(privateKey);
			ui = new MyUserInfo();
		
		Session session = jsch.getSession(userName, host, 22);
		session.setUserInfo(ui);

		boolean connected = false;
		long sessionStartTime = System.currentTimeMillis();
		long timeout = 600000;
		while (!connected) {
			try {
				session.connect();
				break;
			} catch (Exception e) {
				System.out.println("Unable to connect to IP : " + this.host);
				long sessionEndTime = System.currentTimeMillis();
				if ((sessionEndTime - sessionStartTime) < timeout) {
					Wait.millisec(20000);
				} else
					System.out.println(
							"Connect attempt timed out while connecting to IP : "
									+ this.host);

			}
		}

		return session;
	}
	
	public static class MyUserInfo implements UserInfo {
		String passwd;

		MyUserInfo() {
		}

		MyUserInfo(String pass) {
			this.passwd = pass;
		}

		public String getPassword() {
			return passwd;
		}

		public boolean promptYesNo(String str) {
			return true;
		}

		public String getPassphrase() {
			return null;
		}

		public boolean promptPassphrase(String message) {
			return true;
		}

		public boolean promptPassword(String message) {
			return true;
		}


		public void showMessage(String message) {
			System.out.println("message :" + message);
		}
	

	}

	public static void main(String args[]) 
	{
		RemoteOperations remoteOperationsHandler = new RemoteOperations(
				"vcloud", "/var/lib/dmb/conf/cloudorchestration/golden.pem",
				"204.51.115.128",false);
		String command = "ps ax | grep ldap";
		String result = remoteOperationsHandler.remoteExecute(command);
		System.out.println(result);
	}
}
